import 'dart:convert';
import 'dart:async';
import 'package:http/http.dart' as http;
import '../models/product.dart';

class ApiService {
  static const String base = 'https://dummyjson.com';
  final http.Client _client;

  ApiService({http.Client? client}) : _client = client ?? http.Client();

  Future<List<String>> fetchCategories() async {
    final uri = Uri.parse('$base/products/categories');
    final res = await _client.get(uri).timeout(const Duration(seconds: 12));
    if (res.statusCode != 200) throw Exception('分类加载失败(${res.statusCode})');
    final data = jsonDecode(res.body) as List;
    return data.map((e) => e.toString()).toList();
  }

  Future<ProductPage> getProducts({
    String? query,
    String? category,
    int limit = 20,
    int skip = 0,
  }) async {
    Uri uri;
    if (query != null && query.isNotEmpty) {
      uri = Uri.parse('$base/products/search?q=${Uri.encodeQueryComponent(query)}&limit=$limit&skip=$skip');
    } else if (category != null && category.isNotEmpty) {
      uri = Uri.parse('$base/products/category/${Uri.encodeComponent(category)}?limit=$limit&skip=$skip');
    } else {
      uri = Uri.parse('$base/products?limit=$limit&skip=$skip');
    }

    final res = await _client.get(uri).timeout(const Duration(seconds: 12));
    if (res.statusCode != 200) throw Exception('商品加载失败(${res.statusCode})');
    final data = jsonDecode(res.body) as Map<String, dynamic>;
    final products = (data['products'] as List?)
            ?.map((e) => Product.fromJson(e as Map<String, dynamic>))
            .toList() ??
        const <Product>[];
    return ProductPage(
      products: products,
      total: data['total'] as int? ?? products.length,
      skip: data['skip'] as int? ?? skip,
      limit: data['limit'] as int? ?? limit,
    );
  }

  Future<Product> getProductById(int id) async {
    final uri = Uri.parse('$base/products/$id');
    final res = await _client.get(uri).timeout(const Duration(seconds: 12));
    if (res.statusCode != 200) throw Exception('详情加载失败(${res.statusCode})');
    final data = jsonDecode(res.body) as Map<String, dynamic>;
    return Product.fromJson(data);
  }
}